// Copyright (C) <2018> Intel Corporation
//
// SPDX-License-Identifier: Apache-2.0

'use strict'

// Please change example.com to signaling server's address.
const serverAddress = 'http://192.168.137.130:8095'
let isConn = false

// Please change this STUN and TURN server information.
const rtcConfiguration = {
  iceServers: [
    {
      urls: 'stun:119.97.143.86:3478'
    },
    {
      urls: ['turn:119.97.143.86:3478'],
      credential: '1234',
      username: 'admin'
    }
  ]
  // "iceTransportPolicy": "relay"
}

const signaling = new SignalingChannel()
let publicationForCamera
const p2p = new Owt.P2P.P2PClient(
  {
    audioEncodings: true,
    videoEncodings: [
      {
        codec: {
          name: 'h264'
        }
      },
      {
        codec: {
          name: 'vp9'
        }
      },
      {
        codec: {
          name: 'vp8'
        }
      }
    ],
    rtcConfiguration
  },
  signaling
)

let localStream
let screenStream
let statsTask

let videoSize = {
  width: 0,
  height: 0
}
let resolution = {
  width: 0,
  height: 0
}
const getTargetId = function () {
  return $('#remote-uid').val()
}

$(document).ready(function () {
  $('#set-remote-uid').click(function () {
    p2p.allowedRemoteIds = [getTargetId()]
  })

  $('#mute-toggle').click(function () {
    document.getElementById('remoteVideo').muted = !document.getElementById('remoteVideo').muted
    document.getElementById('screenVideo').muted = !document.getElementById('screenVideo').muted
  })

  $('#target-screen').click(function () {
    const config = {
      audio: {
        source: 'screen-cast'
      },
      video: {
        source: 'screen-cast'
      }
    }
    let mediaStream
    Owt.Base.MediaStreamFactory.createMediaStream(config).then(
      (stream) => {
        mediaStream = stream
        screenStream = new Owt.Base.LocalStream(
          mediaStream,
          new Owt.Base.StreamSourceInfo('screen-cast', 'screen-cast')
        )
        $('#local').children('video').get(0).srcObject = screenStream.mediaStream
        p2p.publish(getTargetId(), screenStream).then((publication) => {}),
          (error) => {
            console.log('Failed to share screen.')
          }
      },
      (err) => {
        console.error('Failed to create MediaStream, ' + err)
      }
    )
  })

  $('#target-video-unpublish').click(function () {
    $('#target-video-publish').prop('disabled', false)
    $('#target-video-unpublish').prop('disabled', true)
    publicationForCamera.stop()
    for (const track of localStream.mediaStream.getTracks()) {
      track.stop()
    }
    localStream = undefined
  })

  $('#target-video-publish').click(function () {
    $('#target-video-unpublish').prop('disabled', false)
    $('#target-video-publish').prop('disabled', true)
    if (localStream) {
      p2p.publish(getTargetId(), localStream).then(
        (publication) => {
          publicationForCamera = publication
        },
        (error) => {
          console.log('Failed to share video.')
        }
      ) // Publish local stream to remote client
    } else {
      const audioConstraintsForMic = new Owt.Base.AudioTrackConstraints(
        Owt.Base.AudioSourceInfo.MIC
      )
      const videoConstraintsForCamera = new Owt.Base.VideoTrackConstraints(
        Owt.Base.VideoSourceInfo.CAMERA
      )
      let mediaStream
      Owt.Base.MediaStreamFactory.createMediaStream(
        new Owt.Base.StreamConstraints(audioConstraintsForMic, videoConstraintsForCamera)
      ).then(
        (stream) => {
          mediaStream = stream
          localStream = new Owt.Base.LocalStream(
            mediaStream,
            new Owt.Base.StreamSourceInfo('mic', 'camera')
          )
          $('#local').children('video').get(0).srcObject = localStream.mediaStream
          p2p.publish(getTargetId(), localStream).then(
            (publication) => {
              publicationForCamera = publication
            },
            (error) => {
              console.log('Failed to share video.')
            }
          )
        },
        (err) => {
          console.error('Failed to create MediaStream, ' + err)
        }
      )
    }
  })

  $('#target-peerconnection-stop').click(function () {
    p2p.stop(getTargetId()) // Stop conversation
  })

  $('#login').click(function () {
    p2p
      .connect({
        host: serverAddress,
        token: $('#uid').val()
      })
      .then(
        () => {
          isConn = true

          $('#uid').prop('disabled', true)
        },
        (error) => {
          console.log('Failed to connect to the signaling server.')
        }
      ) // Connect to signaling server.
  })

  $('#logoff').click(function () {
    p2p.disconnect()
    isConn = false
    $('#uid').prop('disabled', false)
  })

  $('#data-send').click(function () {
    p2p.send(getTargetId(), $('#dataSent').val()) // Send data to remote endpoint.
  })
})

p2p.addEventListener('streamadded', function (e) {
  // A remote stream is available.
  e.stream.addEventListener('ended', () => {
    clearInterval(statsTask)
    $('#control').show()
    $('#sendreceive').show()
    $('#local').show()
    $('#stats').hide()
    console.log('Stream is removed.')
  })
  resolution.width = $('#remoteVideo').width()
  resolution.height = $('#remoteVideo').height()
  var data = {
    event: 'size',
    w: resolution.width,
    h: resolution.height
  }
  p2p.send(getTargetId(), JSON.stringify(data))

  $('#control').hide()
  $('#sendreceive').hide()
  $('#local').hide()
  $('#stats').show()
  if (e.stream.source.audio || e.stream.source.video) {
    $('#remoteVideo').show()
    $('#remoteVideo').get(0).srcObject = e.stream.mediaStream
    $('#remoteVideo').get(0).play()
    $('#remoteVideo').get(0).muted = false
  }

  statsTask = setInterval(() => {
    p2p.getStats(getTargetId()).then((statsResult) => {
      statsResult.forEach((stats) => {
        if (stats.type === 'inbound-rtp' && stats.kind === 'video') {
          console.log(stats)
          let txt = `
            <p>fps:${stats.framesPerSecond}</p>
            <p>frameSize:${stats.frameWidth}x${stats.frameHeight}</p>
            <p>framesReceived:${stats.framesReceived},framesDecoded:${stats.framesDecoded}</p>
            <p>jitter:${stats.jitter}</p>
            <p>jitterBufferDelay:${
              stats.jitterBufferDelay / (stats.jitterBufferEmittedCount / 1000)
            }</p>
            <p>packetsLost:${stats.packetsLost}</p>
            <p>totalDecodeTime:${stats.totalDecodeTime}</p>
            `
          $('#stats').html(txt)
        }
      })
    })
  }, 1000)
})

p2p.addEventListener('messagereceived', function (e) {
  // Received data from datachannel.
  $('#dataReceived').val(e.origin + ': ' + e.message)
})

window.onbeforeunload = function () {
  p2p.stop(getTargetId())
}

// document.getElementById('remoteVideo').addEventListener("click",e=>{
//   console.log(e);
// });

$(() => {
  var video = document.getElementById('remoteVideo')
  video.addEventListener('mousemove', (e) => {
    var data = {
      type: 'mousemove',
      x: e.offsetX,
      y: e.offsetY
    }
    if (isConn) {
      //p2p.send(getTargetId(),JSON.stringify(data));
    }
  })
})
